
package com.mancj.slideup;

import ohos.agp.components.Component;
import ohos.multimodalinput.event.TouchEvent;

/**
 * Vertical touch consumer
 *
 * @author pa.gulko zTrap (05.07.2017)
 */
class VerticalTouchConsumer extends TouchConsumer {
    /**
     * * The constant TAG
     */
    public static final String TAG = "VerticalTouchConsumer";
    /**
     * The constant M going up
     */
    private boolean mGoingUp = false;
    /**
     * The constant M going down
     */
    private boolean mGoingDown = false;
    private float startY = -1;

    /**
     * Vertical touch consumer
     *
     * @param builder            builder
     * @param notifier           notifier
     * @param animationProcessor animation processor
     */
    VerticalTouchConsumer(SlideUpBuilder builder, LoggerNotifier notifier, AnimationProcessor animationProcessor) {
        super(builder, notifier, animationProcessor);
    }

    /**
     * Consume bottom to top boolean
     *
     * @param touchedView touched view
     * @param event       event
     * @return the boolean
     */
    boolean consumeBottomToTop(Component touchedView, TouchEvent event) {
        float touchedArea = event.getPointerPosition(0).getY();
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mViewHeight = mBuilder.mSliderView.getHeight();
                startY = mBuilder.mSliderView.getTranslationY();
                mStartPositionY = event.getPointerScreenPosition(0).getY();
                mViewStartPositionY = mBuilder.mSliderView.getTranslationY();
                mCanSlide = touchFromAlsoSlide(touchedView, event);
                mCanSlide |= mBuilder.mTouchableArea >= (touchedArea - mBuilder.locationOnScreenY);
                break;
            case TouchEvent.POINT_MOVE:
                float difference = event.getPointerScreenPosition(0).getY() - mStartPositionY;
                float moveTo = mViewStartPositionY + difference;
                float percents = moveTo * 100 / mBuilder.mSliderView.getHeight();
                calculateDirection(event);
                if (moveTo > 0 && mCanSlide) {
                    mNotifier.notifyPercentChanged(percents);
                    mBuilder.mSliderView.setTranslationY(moveTo);
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                float slideAnimationFrom = mBuilder.mSliderView.getTranslationY();
                if (slideAnimationFrom == mViewStartPositionY) {
                    return !Internal.isUpEventInView(mBuilder.mSliderView, event, mBuilder.locationOnScreenX, mBuilder.locationOnScreenY);
                }
                float translationY = mBuilder.mSliderView.getTranslationY();
                int height = mBuilder.mSliderView.getHeight();
                LogUtil.info(TAG, " translationY: " + translationY + " height: " + height);
                boolean scrollableAreaConsumed = mBuilder.mSliderView.getTranslationY() > mBuilder.mSliderView.getHeight() / 5;
                if (scrollableAreaConsumed && mGoingDown) {
                    mGoingDown = false;
                    mAnimationProcessor.setValuesAndStart(slideAnimationFrom, mBuilder.mSliderView.getHeight());
                } else {
                    mAnimationProcessor.setValuesAndStart(slideAnimationFrom, 0);
                }
                mCanSlide = true;
                mGoingUp = false;
                mGoingDown = false;
                break;
        }
        mPrevPositionY = event.getPointerScreenPosition(0).getY();
        mPrevPositionX = event.getPointerScreenPosition(0).getX();
        return true;
    }

    /**
     * Consume top to bottom boolean
     *
     * @param touchedView touched view
     * @param event       event
     * @return the boolean
     */
    boolean consumeTopToBottom(Component touchedView, TouchEvent event) {
        float touchedArea = event.getPointerPosition(0).getY();
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mViewHeight = mBuilder.mSliderView.getHeight();
                mStartPositionY = event.getPointerScreenPosition(0).getY();
                mViewStartPositionY = mBuilder.mSliderView.getTranslationY();
                mCanSlide = touchFromAlsoSlide(touchedView, event);
                mCanSlide |= getBottom() - mBuilder.mTouchableArea <= touchedArea;
                LogUtil.info(TAG, "consumeTopToBottom: : PRIMARY_POINT_DOWN"
                        + " getY(): " + event.getPointerScreenPosition(0).getY()
                        + " mStartPositionY: " + mStartPositionY
                        + " mViewStartPositionY: " + mViewStartPositionY);
                break;
            case TouchEvent.POINT_MOVE:
                float difference = event.getPointerScreenPosition(0).getY() - mStartPositionY;
                float moveTo = mViewStartPositionY + difference;
                float percents = moveTo * 100 / -mBuilder.mSliderView.getHeight();
                calculateDirection(event);
                LogUtil.info(TAG, "consumeTopToBottom: difference: " + difference + " mViewStartPositionY: " + mViewStartPositionY
                        + " moveTo: " + moveTo);
                if (moveTo < 0 && mCanSlide) {
                    mNotifier.notifyPercentChanged(percents);
                    mBuilder.mSliderView.setTranslationY(moveTo);
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                float slideAnimationFrom = -mBuilder.mSliderView.getTranslationY();
                if (slideAnimationFrom == mViewStartPositionY) {
                    return !Internal.isUpEventInView(mBuilder.mSliderView, event, mBuilder.locationOnScreenX, mBuilder.locationOnScreenY);
                }
                boolean scrollableAreaConsumed = mBuilder.mSliderView.getTranslationY() < -mBuilder.mSliderView.getHeight() / 5;
                int height = mBuilder.mSliderView.getHeight();
                int top = mBuilder.mSliderView.getTop();
                LogUtil.info(TAG, "consumeTopToBottom: top: " + top + " height: " + height);
                if (scrollableAreaConsumed && mGoingUp) {
                    mGoingUp = false;
                    mAnimationProcessor.setValuesAndStart(-slideAnimationFrom, -mBuilder.mSliderView.getHeight() - mBuilder.mSliderView.getTop());
                } else {
                    mAnimationProcessor.setValuesAndStart(-slideAnimationFrom, 0);
                }
                mCanSlide = true;
                break;
        }
        mPrevPositionY = event.getPointerScreenPosition(0).getY();
        mPrevPositionX = event.getPointerScreenPosition(0).getX();
        return true;
    }

    /**
     * Calculate direction *
     *
     * @param event event
     */
    private void calculateDirection(TouchEvent event) {
        mGoingUp = mPrevPositionY > event.getPointerScreenPosition(0).getY();
        mGoingDown = mPrevPositionY < event.getPointerScreenPosition(0).getY();
    }
}
